<?php
/**
 * 上周小结、本周关注——气象分析
 * Created by PhpStorm.
 * User: Mcat
 * Date: 2019/5/8
 * Time: 15:22
 */

namespace app\api\controller;

use app\facade\WeekInfo;
use think\Exception;
use think\Request;
use think\Db;

class WeatherAnalysis extends BaseController
{
    // 上周开始日期/结束日期
    protected $last_start;
    protected $last_week_end_date;
    // 本周开始日期/结束日期
    protected $start_date;
    protected $end_date;
    // 当前日期
    protected $now_date;
    // 上周七天的日期
    protected $week_time_arr; // 格式 Y-m-d H:i:s
    protected $formal_week_time_arr; // 格式 m/d
    // 本周七天的日期
    protected $this_week_time_arr; // 格式 Y-m-d H:i:s
    protected $formal_this_week_time_arr; // 格式 m/d

    public function __construct(Request $request)
    {
        parent::__construct($request);
        $this->getSearchDate();
        $this->getLastWeek();
        $this->getThisWeek();
    }

    /**
     * 获取上周一周的日期
     * @author Mcat
     */
    private function getSearchDate()
    {
        //当前日期
        $date = date('Y-m-d');
        //$first =1 表示每周星期一为开始日期 0表示每周日为开始日期
        $first = 1;
        //获取当前周的第几天 周日是 0 周一到周六是 1 - 6
        $w = date('w', strtotime($date));
        //获取本周开始日期，如果$w是0，则表示周日，减去 6 天
        $now_start = date('Y-m-d', strtotime("$date -" . ($w ? $w - $first : 6) . ' days'));
        $now_end = date('Y-m-d', strtotime("$now_start +6 days"));  //本周结束日期
        $last_start = date('Y-m-d', strtotime("$now_start - 7 days"));  //上周开始日期
        $last_end = date('Y-m-d', strtotime("$now_start - 1 days"));  //上周结束日期
        //获取上周起始/截止日期
        $this->last_start = $last_start;
        $this->last_week_end_date = $last_end;
        //获取本周起始/截止日期
        $this->start_date = $now_start;
        $this->end_date = $now_end;
        //当天日期
        $this->now_date = $date . ' 00:00:00';
    }

    /**
     * 存放上周七天日期
     * @author Mcat
     */
    private function getLastWeek()
    {
        for ($i = 0; $i < 7; $i++) {
            $this->week_time_arr[] = date('Y-m-d H:i:s', strtotime("$this->last_start + $i days"));
            $this->formal_week_time_arr[] = date('m/d', strtotime("$this->last_start + $i days"));
        }
    }

    /**
     * 存放本周七天日期
     * @author Mcat
     */
    private function getThisWeek()
    {
        for ($i = 0; $i < 7; $i++) {
            $this->this_week_time_arr[] = date('Y-m-d H:i:s', strtotime("$this->start_date + $i days"));
            $this->formal_this_week_time_arr[] = date('m/d', strtotime("$this->start_date + $i days"));
        }
    }


    /**
     * 上周小结——首要污染物
     * @author Mcat
     * 查询首要污染物
     * ======================
     * step 1: 查询 `air_quality_station_primary_pollutant_realtime_day`
     * step 2: 如果存在O3 和 O3_8H 取O3值 去掉O3_8H
     *         如果不存在O3 存在O3_8H 取O3_8H浓度值 将name该为O3
     * step 3: 处理得到的数据，返回需要的json格式
     * 注：存在没有首要污染物的情况
     * ======================
     */
    public function lastPrimaryPollutant()
    {
        // 区域ID 默认 53 长治市
        $region_id = $this->request->param('region_id', 53);
        // 站点ID 默认 0 全市
        $station_id = $this->request->param('station_id', 0);
        $last_primary_pollutant_data = WeekInfo::getLastPrimaryPollutant($region_id, $station_id, $this->last_start, $this->last_week_end_date);
        $num = count($last_primary_pollutant_data);
        try {
            if ($last_primary_pollutant_data) {
                foreach ($last_primary_pollutant_data as $key => $val) {
                    if (strtoupper($val['name']) == 'O3_8H') {
                        if ($key > 0 && $key < $num - 1) {
                            if ($last_primary_pollutant_data[$key - 1]['publish_time'] == $val['publish_time'] || $last_primary_pollutant_data[$key + 1]['publish_time'] == $val['publish_time']) {
                                if (strtoupper($last_primary_pollutant_data[$key - 1]['name']) == 'O3' || strtoupper($last_primary_pollutant_data[$key + 1]['name']) == 'O3') {
                                    $last_primary_pollutant_data[$key] = '';
                                }
                            }
                        }
                        $last_primary_pollutant_data[$key]['name'] = 'O3';
                    } else {
                        $last_primary_pollutant_data[$key]['name'] = strtoupper($val['name']);
                    }
                }

                // 将$last_primary_pollutant_data 降一维 将publish_time字段值取出
                $publish_time_arr = array_column($last_primary_pollutant_data, 'publish_time');
                // 获取每天首要污染物的个数
                $repeat_info_arr = array_count_values($publish_time_arr);
                // 首要污染物出现最多次数
                $max_primary_pollutant_num = max($repeat_info_arr);
                // 存放正式数据
                $formal = [];
                // 将上周日期转为字符串存入
                $formal['date'] = $this->formal_week_time_arr;
                // 将数组处理为接口需求格式
                for ($i = 0; $i < $max_primary_pollutant_num; $i++) {
                    for ($a = 0; $a < 7; $a++) {
                        // 通过固定上周日期查找，数组中的下标值 存在返回下标 不存在返回false
                        $sub_num = array_search($this->week_time_arr[$a], $publish_time_arr);
                        if ($sub_num !== false) {// 存在首要污染物的日期
                            // 通过日期获取 name 和 value值
                            $formal['data'][$i][$a] = [
                                'name' => $last_primary_pollutant_data[$sub_num]['name'],
                                'value' => $last_primary_pollutant_data[$sub_num]['value']
                            ];
                            unset($last_primary_pollutant_data[$sub_num]);
                            unset($publish_time_arr[$sub_num]);
                        } else {// 不存在首要污染物日期
                            $formal['data'][$i][$a] = '';
                        }
                    }
                }
            } else {
                $formal['date'] = $this->formal_week_time_arr;
                $formal['data'] = [];
            }
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }

        $this->success("首要污染物", $formal);
    }

    /**
     * 上周小结——相关污染物
     * @author Mcat
     * ======================
     * step 1: 查询 `air_quality_station_relevance_pollutant_realtime_day` 获取相关污染物
     * step 2: 查询 `air_quality_station_aqi_realtime_day` 获取选取时间中每天的六参浓度值
     * step 3: 将相关污染物的对应浓度值获取
     * step 4: 如果存在O3 和 O3_8H 取O3值 去掉O3_8H
     *         如果不存在O3 存在O3_8H 取O3_8H浓度值 将name该为O3
     * step 5: 处理得到的数据，返回需要的json格式
     * 注：存在没有相关污染物的情况
     * ======================
     */
    public function lastRelatedPollutant()
    {
        // 区域ID 默认 53 长治市
        $region_id = $this->request->param('region_id', 53);
        // 站点ID 默认 1 长治八中
        $station_id = $this->request->param('station_id', 1);
        if ($station_id == 0) {
            $this->error('站点不可为全市');
        }
        // 获取上周相关污染物的数据
        $relevance_pollutant_data = WeekInfo::getLastRelatedPollutant($region_id, $station_id, $this->last_start, $this->last_week_end_date);
        $relevance_pollutant_val_data = WeekInfo::getLastRelatedPollutantValue($region_id, $station_id, $this->last_start, $this->last_week_end_date);
        try {
            // 用于处理数据
            $relevance_pollutant_data_process = []; // 获取到去除重复数据的 相关污染物
            $relevance_pollutant_max_num_process = []; // 用户获取最多污染物的个数
            $formal = []; // 正式数据
            // 获取相关污染物 并 将重复的污染物去除
            foreach ($relevance_pollutant_data as $key => $value) {
                if (array_key_exists($value['publish_time'], $relevance_pollutant_data_process)) {
                    if (!in_array($value['relevance_name'], $relevance_pollutant_data_process[$value['publish_time']])) {
                        $relevance_pollutant_data_process[$value['publish_time']][] = $value['relevance_name'];
                    }
                } else {
                    $relevance_pollutant_data_process[$value['publish_time']][] = $value['relevance_name'];
                }
            }
            if ($relevance_pollutant_data_process) {
                // 获取相关污染物最多的个数
                foreach ($relevance_pollutant_data_process as $key => $value) {
                    $relevance_pollutant_max_num_process[$key] = count($value);
                }
                $max_relevance_pollutant_num = max($relevance_pollutant_max_num_process);

                // 将上周日期转为字符串存入
                $formal['date'] = $this->formal_week_time_arr;
                // 将数组处理为接口需求格式 —— 获取到相关污染物的值
                for ($i = 0; $i < $max_relevance_pollutant_num; $i++) {
                    for ($a = 0; $a < 7; $a++) {
                        // 通过固定上周日期查找，判断数组中是否存在
                        $is_exit = array_key_exists($this->week_time_arr[$a], $relevance_pollutant_data_process);
                        if ($is_exit && isset($relevance_pollutant_data_process[$this->week_time_arr[$a]][0])) {
                            $formal['data'][$i][$a] = [
                                'name' => $relevance_pollutant_data_process[$this->week_time_arr[$a]][0],
                                'value' => $relevance_pollutant_val_data[$a][str_replace(array("_", "."), '', strtolower($relevance_pollutant_data_process[$this->week_time_arr[$a]][0]))]
                            ];
                            array_splice($relevance_pollutant_data_process[$this->week_time_arr[$a]], 0, 1);
                        } else {
                            $formal['data'][$i][$a] = '';
                        }
                    }
                }

                if (count($formal['data']) > 1) {
                    for ($i = 1; $i < count($formal['data']); $i++) {
                        foreach ($formal['data'][0] as $k => $v) {
                            if (!empty($v)) {
                                if (strtoupper($v['name']) == 'PM25') {
                                    $v['name'] = 'PM2.5';
                                }
                                if (strtoupper($v['name']) == 'O3' && strtoupper($formal['data'][$i][$k]['name']) == 'O3_8H') {
                                    $formal['data'][$i][$k] = '';
                                } elseif (strtoupper($v['name']) == 'O3_8H' && strtoupper($formal['data'][$i][$k]['name']) == 'O3') {
                                    $formal['data'][0][$k] = '';
                                } elseif (strtoupper($v['name']) == 'O3_8H' && strtoupper($formal['data'][$i][$k]['name']) != 'O3') {
                                    $formal['data'][0][$k]['name'] = 'O3';
                                } else {
                                    $formal['data'][0][$k]['name'] = strtoupper($v['name']);
                                    $formal['data'][$i][$k]['name'] = strtoupper($formal['data'][$i][$k]['name']);
                                }
                            }
                        }
                    }
                } else {
                    foreach ($formal['data'][0] as $k => $v) {
                        if (!empty($v)) {
                            if (strtoupper($v['name']) == 'PM25') {
                                $v['name'] = 'PM2.5';
                            }
                            if (strtoupper($v['name']) == 'O3_8H') {
                                $formal['data'][0][$k]['name'] == 'O3';
                            } else {
                                $formal['data'][0][$k]['name'] == strtoupper($v['name']);
                            }
                        }

                    }
                }
            } else {
                $formal['date'] = $this->formal_week_time_arr;
                $formal['data'] = [];
            }
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        $this->success('上周小结——相关污染物', $formal);
    }


    /**
     * 上周小结——首要污染物相关站点
     * @author Mcat
     * ======================
     * step 1: 查询 `air_quality_station_primary_pollutant_realtime_day` 获得选中站点的每天首要污染物
     * step 2: 查询 `air_quality_station_aqi_realtime_hour` 通过首要污染物查询每个站点24h的该污染物浓度值
     * step 3: 将选中站点的24h 浓度值 去和其他站点比较 得到皮尔逊系数 皮尔逊计算公式方法——correlationAnalysis()
     * 注: O3 和 O3_8H 按两种污染物处理
     * ======================
     */
    public function lastPrimaryPollutantRelated()
    {
        /*
         * 一：先获取到上周首要污染物并处理为接口格式
         * $primary_pollutant_formal[污染物个数][七天][污染物名称]
         * */
        // 区域ID 默认 53 长治市
        $region_id = $this->request->param('region_id', 53);
        // 站点ID 默认 1 长治八中
        $station_id = $this->request->param('station_id', 1);
        if ($station_id == 0) {
            $this->error('站点不可为全市');
        }
        // 上周首要污染物
        $last_primary_pollutant_data = WeekInfo::getLastPrimaryPollutant($region_id, $station_id, $this->last_start, $this->last_week_end_date);
        $publish_time_arr = array_column($last_primary_pollutant_data, 'publish_time');
        // 获取每天首要污染物的个数
        $repeat_info_arr = array_count_values($publish_time_arr);
        // 首要污染物出现最多次数
        $max_primary_pollutant_num = max($repeat_info_arr);
        // 将首要污染物获取并处理成接口格式存放入 $primary_pollutant_formal
        $primary_pollutant_formal = array();
        for ($i = 0; $i < $max_primary_pollutant_num; $i++) {
            for ($a = 0; $a < 7; $a++) {
                // 通过固定上周日期查找，数组中的下标值 存在返回下标 不存在返回false
                $sub_num = array_search($this->week_time_arr[$a], $publish_time_arr);
                if ($sub_num !== false) {// 存在首要污染物的日期
                    // 通过日期获取 name 和 value值
                    $primary_pollutant_formal[$i][$a] = $last_primary_pollutant_data[$sub_num]['name'];
                    unset($last_primary_pollutant_data[$sub_num]);
                    unset($publish_time_arr[$sub_num]);
                } else {// 不存在首要污染物日期
                    $primary_pollutant_formal[$i][$a] = '';
                }
            }
        }
        /**
         * 根据得到上周首要污染物的类型 查询上周七天首要污染物 24h 全部站点的浓度值 $Last_24h_data[首要污染物个数][七天0-6下标][五个站点该首要污染物24h浓度值]
         */
        $last_24h_data = array();
        for ($x = 0; $x < count($primary_pollutant_formal); $x++) {
            for ($i = 0; $i < 7; $i++) {
                $start = $this->week_time_arr[$i];
                $end = date('Y-m-d 11:59:59', strtotime("$start"));
                if ($primary_pollutant_formal[$x][$i]) {
                    if ($primary_pollutant_formal[$x][$i] == 'PM2.5') {
                        $last_24h_data[$x][$i] = WeekInfo::getLastSiteConcentration24h($region_id, $start, $end, 'PM25');
                    } else {
                        $last_24h_data[$x][$i] = WeekInfo::getLastSiteConcentration24h($region_id, $start, $end, $primary_pollutant_formal[$x][$i]);
                    }
                } else {
                    $last_24h_data[$x][$i] = '';
                }
            }
        }
        /*
         * 将站点之间相互比较获取皮尔逊值
         * */
        $site_arr = [1, 2, 3, 4, 5]; // 站点值数组
        unset($site_arr[$station_id - 1]);
        $site_name = ['长治八中', '德盛苑', '监测站', '清华站', '审计局']; //站点对应名称
        $result['date'] = $this->formal_week_time_arr;
        $arr_n = 0;
        foreach ($last_24h_data as $key => $val) {
            foreach ($site_arr as $i => $s) {
                foreach ($val as $k => $v) {
                    if ($v && count($v[$station_id]) > 19) {
                        //start zhugeng  update 处理两个对比数组数据，两个数组中的日期相等且每小时污染物的值大于0
                        $arr1 = [];
                        $arr2 = [];
                        foreach ($v[$station_id] as $k1 => $v1) {
                            foreach ($v[$s] as $k2 => $v2) {
                                if ($k1 == $k2 && $v1 > 0 && $v2 > 0) {
                                    $arr1[] = $v1;
                                    $arr2[] = $v2;
                                }
                            }
                        }

                        // 获取皮尔逊值 四舍五入 保留两位
                        if (count($arr1) >= 20 && count($arr2) >= 20) {//zhugeng 上面处理完的每个数组不小于20小时，才能进行比较
                            $pearson_value = correlationAnalysis($v[$station_id], $v[$s]);
                            $pearson_value = sprintf("%.2f", $pearson_value);
                            if ($pearson_value >= 0.75) {
                                $result['data'][$i - 1][] = ['name' => $site_name[$i], 'value' => $pearson_value];
                            } else {
                                $result['data'][$i - 1][] = ['name' => '', 'value' => ''];
                            }
                        }
                    } else {
                        $result['data'][$i - 1][] = ['name' => '', 'value' => ''];
                    }
                    //end zhugeng
                }
//                $arr_n++;
            }
        }
        $this->success('上周小结——首要污染物相关站点', $result);
    }


    /**
     * 本周——首要污染物
     * @author Mcat
     * ======================
     * step 1: 查询 `air_quality_station_primary_pollutant_realtime_day` `air_quality_station_primary_pollutant_forecast_day`
     * step 2: 如果存在O3 和 O3_8H 取O3值 去掉O3_8H
     *         如果不存在O3 存在O3_8H 取O3_8H浓度值 将name该为O3
     * step 3: 处理得到的数据，返回需要的json格式
     * 注：存在没有首要污染物的情况
     * ======================
     */
    public function thisPrimaryPollutant()
    {
        // 区域ID 默认 53 长治市
        $region_id = $this->request->param('region_id', 53);
        // 站点ID 默认 0 全市
        $station_id = $this->request->param('station_id', 0);
        // 本周实测值
        $last_practical_data = WeekInfo::getLastPrimaryPollutant($region_id, $station_id, $this->start_date, date('Y-m-d H:i:s', strtotime("$this->now_date - 1 days")));
        // 本周预报值
        $this_forecast_data = WeekInfo::getThisPrimaryPollutant($region_id, $station_id, $this->now_date, $this->end_date);
        try {
            $this_primary_pollutant_data = array_merge($last_practical_data, $this_forecast_data);
            if ($this_primary_pollutant_data) {
                $num = count($this_primary_pollutant_data);
                foreach ($this_primary_pollutant_data as $key => $val) {
                    if (strtoupper($val['name']) == 'O3_8H') {
                        if ($key > 0 && $key < $num - 1) {
                            if ($this_primary_pollutant_data[$key - 1]['publish_time'] == $val['publish_time'] || $this_primary_pollutant_data[$key + 1]['publish_time'] == $val['publish_time']) {
                                if (strtoupper($this_primary_pollutant_data[$key - 1]['name']) == 'O3' || strtoupper($this_primary_pollutant_data[$key + 1]['name']) == 'O3') {
                                    $this_primary_pollutant_data[$key] = '';
                                }
                            }
                        }
                        $this_primary_pollutant_data[$key]['name'] = 'O3';
                    } else {
                        $this_primary_pollutant_data[$key]['name'] = strtoupper($val['name']);
                    }
                }

                // 将$last_primary_pollutant_data 降一维 将publish_time字段值取出
                $publish_time_arr = array_column($this_primary_pollutant_data, 'publish_time');
                // 获取每天首要污染物的个数
                $repeat_info_arr = array_count_values($publish_time_arr);
                // 首要污染物出现最多次数
                $max_primary_pollutant_num = max($repeat_info_arr);
                // 存放正式数据
                $formal = [];
                // 将上周日期转为字符串存入
                $formal['date'] = $this->formal_this_week_time_arr;
                // 将数组处理为接口需求格式
                for ($i = 0; $i < $max_primary_pollutant_num; $i++) {
                    for ($a = 0; $a < 7; $a++) {
                        // 通过固定上周日期查找，数组中的下标值 存在返回下标 不存在返回false
                        $sub_num = array_search($this->this_week_time_arr[$a], $publish_time_arr);
                        if ($sub_num !== false) {// 存在首要污染物的日期
                            // 通过日期获取 name 和 value值
                            $formal['data'][$i][$a] = [
                                'name' => $this_primary_pollutant_data[$sub_num]['name'],
                                'value' => $this_primary_pollutant_data[$sub_num]['value']
                            ];
                            unset($this_primary_pollutant_data[$sub_num]);
                            unset($publish_time_arr[$sub_num]);
                        } else {// 不存在首要污染物日期
                            $formal['data'][$i][$a] = '';
                        }
                    }
                }
            } else {
                $formal['date'] = $this->formal_this_week_time_arr;
                $formal['data'] = [];
            }
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        $this->success("首要污染物", $formal);
    }

    /**
     * 获取本周相关污染物
     * @author Mcat
     * ======================
     * step 1: 查询 `air_quality_station_relevance_pollutant_realtime_day` `air_quality_station_relevance_pollutant_forecast_day`获取相关污染物
     * step 2: 查询 `air_quality_station_aqi_realtime_day` `air_quality_station_aqi_forecast_day`获取选取时间中每天的六参浓度值
     * step 3: 将相关污染物的对应浓度值获取
     * step 4: 如果存在O3 和 O3_8H 取O3值 去掉O3_8H
     *         如果不存在O3 存在O3_8H 取O3_8H浓度值 将name该为O3
     * step 5: 处理得到的数据，返回需要的json格式
     * 注：存在没有相关污染物的情况
     * ======================
     */
    public function thisRelatedPollutant()
    {
        // 区域ID 默认 53 长治市
        $region_id = $this->request->param('region_id', 53);
        // 站点ID 默认 0 全市
        $station_id = $this->request->param('station_id', 1);
        if ($station_id == 0) {
            $this->error('参数错误');
        }
        // 获取本周实测相关污染物的数据
        $relevance_pollutant_data = WeekInfo::getLastRelatedPollutant($region_id, $station_id, $this->start_date, date('Y-m-d H:i:s', strtotime("$this->now_date - 1 days")));
        // 获取本周预测相关污染物的数据
        $this_relevance_pollutant_data = WeekInfo::getThisRelatedPollutant($region_id, $station_id, $this->now_date, $this->end_date);
        // 将相关污染物的数据合并
        $formal_relevance_pollutant_data = array_merge($relevance_pollutant_data, $this_relevance_pollutant_data);
        // 获取实测污染物浓度值
        $relevance_pollutant_val_data = WeekInfo::getLastRelatedPollutantValue($region_id, $station_id, $this->start_date, date('Y-m-d H:i:s', strtotime("$this->now_date - 1 days")));
        // 获取预测污染物浓度值
        $this_relevance_pollutant_val_data = WeekInfo::getThisRelatedPollutantValue($region_id, $station_id, $this->now_date, $this->end_date);
        // 将污染物的浓度值合并
        $formal_relevance_pollutant_val_data = array_merge($relevance_pollutant_val_data, $this_relevance_pollutant_val_data);
        try {
            // 用于处理数据
            $relevance_pollutant_data_process = []; // 获取到去除重复数据的 相关污染物
            $relevance_pollutant_max_num_process = []; // 用户获取最多污染物的个数
            $formal = []; // 正式数据
            // 获取相关污染物 并 将重复的污染物去除
            foreach ($formal_relevance_pollutant_data as $key => $value) {
                if (array_key_exists($value['publish_time'], $relevance_pollutant_data_process)) {
                    if (!in_array($value['relevance_name'], $relevance_pollutant_data_process[$value['publish_time']])) {
                        $relevance_pollutant_data_process[$value['publish_time']][] = str_replace(array("_", "."), "", strtolower($value['relevance_name']));
                    }
                } else {
                    $relevance_pollutant_data_process[$value['publish_time']][] = str_replace(array("_", "."), "", strtolower($value['relevance_name']));
                }
            }
            // 获取相关污染物最多的个数
            foreach ($relevance_pollutant_data_process as $key => $value) {
                $relevance_pollutant_max_num_process[$key] = count($value);
            }
            if (!$relevance_pollutant_max_num_process) {
                $formal['date'] = $this->formal_this_week_time_arr;
                $formal['data'] = [];
            } else {
                $max_relevance_pollutant_num = max($relevance_pollutant_max_num_process);
                // 将上周日期转为字符串存入
                $formal['date'] = $this->formal_this_week_time_arr;
                // 将数组处理为接口需求格式 —— 获取到相关污染物的值
                for ($i = 0; $i < $max_relevance_pollutant_num; $i++) {
                    for ($a = 0; $a < 7; $a++) {
                        // 通过固定上周日期查找，判断数组中是否存在
                        $is_exit = array_key_exists($this->this_week_time_arr[$a], $relevance_pollutant_data_process);
                        if ($is_exit && isset($relevance_pollutant_data_process[$this->this_week_time_arr[$a]][0])) {
                            if (isset($formal_relevance_pollutant_val_data[$a])) {
                                $formal['data'][$i][$a] = [
                                    'name' => $relevance_pollutant_data_process[$this->this_week_time_arr[$a]][0],
                                    'value' => $formal_relevance_pollutant_val_data[$a][str_replace(array("_", "."), '', strtolower($relevance_pollutant_data_process[$this->this_week_time_arr[$a]][0]))]
                                ];
                                array_splice($relevance_pollutant_data_process[$this->this_week_time_arr[$a]], 0, 1);
                            } else {
                                $formal['data'][$i][$a] = '';
                            }
                        } else {
                            $formal['data'][$i][$a] = '';
                        }
                    }
                }

                if (count($formal['data']) > 1) {
                    for ($i = 1; $i < count($formal['data']); $i++) {
                        foreach ($formal['data'][0] as $k => $v) {
                            if (!empty($v)) {
                                if (strtoupper($v['name']) == 'PM25') {
                                    $v['name'] = 'PM2.5';
                                }
                                if (strtoupper($v['name']) == 'O3' && strtoupper($formal['data'][$i][$k]['name']) == 'O3_8H') {
                                    $formal['data'][$i][$k] = '';
                                } elseif (strtoupper($v['name']) == 'O3_8H' && strtoupper($formal['data'][$i][$k]['name']) == 'O3') {
                                    $formal['data'][0][$k] = '';
                                } elseif (strtoupper($v['name']) == 'O3_8H' && strtoupper($formal['data'][$i][$k]['name']) != 'O3') {
                                    $formal['data'][0][$k]['name'] = 'O3';
                                } else {
                                    $formal['data'][0][$k]['name'] = strtoupper($v['name']);
                                    $formal['data'][$i][$k]['name'] = strtoupper($formal['data'][$i][$k]['name']);
                                }
                            }
                        }
                    }
                } else {
                    foreach ($formal['data'][0] as $k => $v) {
                        if (!empty($v)) {
                            if (strtoupper($v['name']) == 'PM25') {
                                $v['name'] = 'PM2.5';
                            }
                            if (strtoupper($v['name']) == 'O3_8H') {
                                $formal['data'][0][$k]['name'] == 'O3';
                            } else {
                                $formal['data'][0][$k]['name'] == strtoupper($v['name']);
                            }
                        }
                    }
                }
            }
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        $this->success('上周小结——相关污染物', $formal);
    }

    /**
     * 本周小结——首要污染物相关站点
     * @author Mcat
     * ======================
     * step 1: 查询 `air_quality_station_primary_pollutant_realtime_day` `air_quality_station_primary_pollutant_forecast_day` 获得选中站点的每天首要污染物
     * step 2: 查询 `air_quality_station_aqi_forecast_hour` `air_quality_station_aqi_realtime_hour` 通过首要污染物查询每个站点24h的该污染物浓度值
     * step 3: 将选中站点的24h 浓度值 去和其他站点比较 得到皮尔逊系数 皮尔逊计算公式方法——correlationAnalysis()
     * 注: O3 和 O3_8H 按两种污染物处理
     * ======================
     */
    public function thisPrimaryPollutantRelated()
    {
        /*
         * 一：先获取到上周首要污染物并处理为接口格式
         * $primary_pollutant_formal[污染物个数][七天][污染物名称]
         * */
        // 区域ID 默认 53 长治市
        $region_id = $this->request->param('region_id', 53);
        // 站点ID 默认 1 长治八中
        $station_id = $this->request->param('station_id', 1);
        if ($station_id == 0) {
            $this->error('站点不可为全市');
        }
        // 本周首要污染物 —— 实际
        $last_primary_pollutant_data = WeekInfo::getLastPrimaryPollutant($region_id, $station_id, $this->start_date, date('Y-m-d H:i:s', strtotime("$this->now_date - 1 days")));
        // 本周首要污染物——预测
        $this_forecast_data = WeekInfo::getThisPrimaryPollutant($region_id, $station_id, $this->now_date, $this->end_date);
        // 合并本周数据
        $this_primary_pollutant_data = array_merge($last_primary_pollutant_data, $this_forecast_data);
        if (!empty($last_primary_pollutant_data) || !empty($this_forecast_data)) {
            $publish_time_arr = array_column($this_primary_pollutant_data, 'publish_time');
            // 获取每天首要污染物的个数
            $repeat_info_arr = array_count_values($publish_time_arr);
            // 首要污染物出现最多次数
            $max_primary_pollutant_num = max($repeat_info_arr);
            // 将首要污染物获取并处理成接口格式存放入 $primary_pollutant_formal
            $primary_pollutant_formal = array();
            for ($i = 0; $i < $max_primary_pollutant_num; $i++) {
                for ($a = 0; $a < 7; $a++) {
                    // 通过固定上周日期查找，数组中的下标值 存在返回下标 不存在返回false
                    $sub_num = array_search($this->this_week_time_arr[$a], $publish_time_arr);
                    if ($sub_num !== false) {// 存在首要污染物的日期
                        // 通过日期获取 name 和 value值
                        $primary_pollutant_formal[$i][$a] = $this_primary_pollutant_data[$sub_num]['name'];
                        unset($this_primary_pollutant_data[$sub_num]);
                        unset($publish_time_arr[$sub_num]);
                    } else {// 不存在首要污染物日期
                        $primary_pollutant_formal[$i][$a] = '';
                    }
                }
            }
        } else {
            $primary_pollutant_formal = '';
        }
        /**
         * 根据得到上周首要污染物的类型 查询上周七天首要污染物 24h 全部站点的浓度值 $this_24h_data/$Last_24h_data[首要污染物个数][七天0-6下标][五个站点该首要污染物24h浓度值]
         */
        $week_24h_data = array();
        $now_time = date('Y-m-d 00:00:00', time());
        for ($x = 0; $x < count($primary_pollutant_formal); $x++) {
            for ($i = 0; $i < 7; $i++) {
                $start = $this->this_week_time_arr[$i];
                $end = date('Y-m-d 23:59:59', strtotime("$start"));
                if ($start >= $now_time) {
                    //预测数据
                    if ($primary_pollutant_formal[$x][$i]) {
                        if ($primary_pollutant_formal[$x][$i] == 'PM2.5') {
                            $week_24h_data[$x][$i] = WeekInfo::getThisSiteConcentration24h($region_id, $start, $end, 'PM25', $now_time);
                        } else {
                            $week_24h_data[$x][$i] = WeekInfo::getThisSiteConcentration24h($region_id, $start, $end, $primary_pollutant_formal[$x][$i], $now_time);
                        }
                    } else {
                        $week_24h_data[$x][$i] = '';
                    }
                } else {
                    //实测数据
                    if ($primary_pollutant_formal[$x][$i]) {
                        $week_24h_data[$x][$i] = WeekInfo::getLastSiteConcentration24h($region_id, $start, $end, $primary_pollutant_formal[$x][$i]);
                    } else {
                        $week_24h_data[$x][$i] = '';
                    }
                }
            }
        }
        /*
         * 将站点之间相互比较获取皮尔逊值
         * */
        $site_arr = [1, 2, 3, 4, 5]; // 站点值数组
        unset($site_arr[$station_id - 1]);
        $site_name = ['长治八中', '德盛苑', '监测站', '清华站', '审计局']; //站点对应名称
        $result['date'] = $this->formal_this_week_time_arr;
        $arr_n = 0;
        foreach ($week_24h_data as $key => $val) {
            foreach ($site_arr as $i => $s) {
                foreach ($val as $k => $v) {
                    if ($v && count($v[$station_id]) > 19) {
                        //start zhugeng  update 处理两个对比数组数据，两个数组中的日期相等且每小时污染物的值大于0
                        $arr1 = [];
                        $arr2 = [];
                        foreach ($v[$station_id] as $k1 => $v1) {
                            foreach ($v[$s] as $k2 => $v2) {
                                if ($k1 == $k2 && $v1 > 0 && $v2 > 0) {
                                    $arr1[] = $v1;
                                    $arr2[] = $v2;
                                }
                            }
                        }
                        // 获取皮尔逊值 四舍五入 保留两位
//                        $pearson_value = correlationAnalysis($v[$station_id], $v[$s]);
                        if (count($arr1) >= 20 && count($arr2) >= 20) {//zhugeng 上面处理完的每个数组不小于20小时，才能进行比较
                            $pearson_value = correlationAnalysis($arr1, $arr2);
                            $pearson_value = sprintf("%.2f", $pearson_value);
                            if ($pearson_value >= 0.75) {
                                $result['data'][$i - 1][] = ['name' => $site_name[$i], 'value' => $pearson_value];
                            } else {
                                $result['data'][$i - 1][] = ['name' => '', 'value' => ''];
                            }
                        } else {
                            $result['data'][$i - 1][] = ['name' => '', 'value' => ''];
                        }

                    } else {
                        $result['data'][$i - 1][] = ['name' => '', 'value' => ''];
                    }
                    //end zhugeng
//                    $arr_n++;
                }
            }

        }
        $this->success('本周小结——首要污染物相关站点', $result);
    }


    /**0
     * 气象环境图
     * zhugeng 2019-06-28
     */
    public function weatherEnvironmentEchart()
    {
        $param = $this->request->param();
        if (empty($param['region_id']) || empty($param['start_date']) || empty($param['end_date']) || empty($param['type'])) {
            $this->error('参数错误');
        }
        //日期列表
        $lastYearWeek = self::getDateFromRangeYear($param['start_date'], $param['end_date']);
        if ($param['type'] == 1) {//上周
            $listAll = $this->getRealtimeStable($param['station_id'],$param['start_date'].' 00:00:00',$param['end_date'].' 23:00:00',$lastYearWeek);
            $list = $listAll[0];
            $publishDate = $listAll[1];
            //查询AQI实际值
            $aqi_sql = 'select aqi,publish_time as dt_time from air_quality_station_aqi_realtime_day where region_id = ? and station_id = ? and publish_time between ? and ?';
            $aqi_list = Db::query($aqi_sql,array($param['region_id'],$param['station_id'],$param['start_date'],$param['end_date']));
        } else {//本周
            if (strtotime($param['start_date']) == strtotime(date('Y-m-d', time()))) {
                //预报
                //预报日期列表
//                $forecastWeek = self::getDateFromRangeYear(date('Y-m-d 00:00:00', time()), $param['end_date'].' 23:00:00');
                //预报
                $listAll = $this->getForecastStable($param['station_id'],date('Y-m-d 00:00:00', time()),$param['end_date'].' 23:00:00',$lastYearWeek);
                $list = $listAll[0];
                $publishDate = $listAll[1];
                //查询AQI预报值
                $aqi_sql = 'select aqi,predict_time as dt_time from air_quality_station_aqi_forecast_day where region_id = ? and station_id = ? and predict_time between ? and ? and publish_time = ?';
                $aqi_list = Db::query($aqi_sql,array($param['region_id'],$param['station_id'],$param['start_date'].' 00:00:00',$param['end_date'].' 23:00:00',date('Y-m-d 00:00:00',time())));
            } else {
                //实际+预报
                //实际日期列表
                $lastWeek = self::getDateFromRangeYear($param['start_date'], date('Y-m-d 00:00:00', strtotime('-1 day')));
                //实际
                $listRealtime = $this->getRealtimeStable($param['station_id'],$param['start_date'].' 00:00:00',date('Y-m-d 23:00:00', strtotime('-1 day')),$lastWeek);
                $list1 = $listRealtime[0];
                $publishDate1 = $listRealtime[1];//发布日期
                //查询AQI实际值
                $aqi_sql1 = 'select aqi,publish_time as dt_time from air_quality_station_aqi_realtime_day where region_id = ? and station_id = ? and publish_time between ? and ?';
                $aqi_list1 = Db::query($aqi_sql1,array($param['region_id'],$param['station_id'],$param['start_date'].' 00:00:00',date('Y-m-d 23:00:00', strtotime('-1 day'))));
                //预报日期列表
                $forecastWeek = self::getDateFromRangeYear(date('Y-m-d 00:00:00', time()), $param['end_date'].' 23:00:00');
                //预报
                $listForecast = $this->getForecastStable($param['station_id'],date('Y-m-d 00:00:00', time()),$param['end_date'].' 23:00:00',$forecastWeek);
                $list2 = $listForecast[0];
                $publishDate2 = $listForecast[1];//发布日期
                //查询AQI预报值
                $aqi_sql2 = 'select aqi,predict_time as dt_time from air_quality_station_aqi_forecast_day where region_id = ? and station_id = ? and predict_time between ? and ? and publish_time = ?';
                $aqi_list2 = Db::query($aqi_sql2,array($param['region_id'],$param['station_id'],date('Y-m-d 00:00:00', time()),$param['end_date'].' 23:00:00',date('Y-m-d 00:00:00',time())));
                $aqi_list = array_merge_recursive($aqi_list1, $aqi_list2);//合并AQI数据
                $list = array_merge_recursive($list1, $list2);//合并静稳指数数据
                $publishDate = array_merge_recursive($publishDate1, $publishDate2);//合并发布日期
            }
        }

        if (count($list) <= 0 && count($aqi_list) <= 0) {
            foreach ($lastYearWeek as $k => $v) {
                $data[$k] = [
                    'date' => date('Y/m/d', strtotime($v)),
                    'aqi' => ['name' => 'AQI', 'value' => 0],
                    'static_index' => ['name' => '静稳指数', 'value' => 0]
                ];
            }
        } else {
            $newList = [];
            $newDate = [];
            foreach ($list as $k => $v) {
                foreach ($aqi_list as $k1 => $v1) {
                    if ($v['pt_time'] == $v1['dt_time']) {
                        $v['aqi_day'] = $v1['aqi'];
                        $newList[date('Y-m-d', strtotime($v['pt_time']))][] = $v;
                        array_push($newDate, date('Y-m-d', strtotime($v['pt_time'])));
                    }
                }
            }
            $newDate = array_values(array_unique($newDate));//去重，重新排列索引
            foreach ($lastYearWeek as $k => $v) {
                if (in_array($v, $newDate)) {
                    if ($newList[$v][0]['aqi_day'] == -1) {
                        $newList[$v][0]['aqi_day'] = 0;
                    }
                    $data[$k] = [
                        'date' => [date('Y/m/d', strtotime($v)),$publishDate[$k],$v.' 00'],
                        'aqi' => ['name' => 'AQI', 'value' => ceil($newList[$v][0]['aqi_day'])],
                        'static_index' => ['name' => '静稳指数', 'value' => round($newList[$v][0]['stable_weather_index_value'], 2)]
                    ];
                } else {
                    $data[$k] = [
                        'date' => [date('Y/m/d', strtotime($v)),$publishDate[$k],$v.' 00'],
                        'aqi' => ['name' => 'AQI', 'value' => 0],
                        'static_index' => ['name' => '静稳指数', 'value' => 0]
                    ];
                }
            }
        }
        $this->success('成功', $data);

    }

    /**
     *   获取静稳指数实测值
     * zhugeng 2019-08-16
     * @param $station_id
     * @param $start_date
     * @param $end_date
     * @param $weekList
     * @return array|mixed
     */
    public function getRealtimeStable($station_id, $start_date, $end_date, $weekList)
    {
        $sql = 'select stable_weather_index_value,aqi_day,predict_time as pt_time from stable_weather_index_realtime_day_new where station_id = ? and predict_time between ? and ?  and predict_time = publish_time';
        $list = Db::query($sql, array($station_id, $start_date, $end_date));
        $resultTime = array_column($list,'pt_time');
        $afterWeek = [];//静稳指数发布日期
        foreach ($weekList as $k => $v) {
            if (!in_array($v.' 00:00:00', $resultTime)) {
                $beforeTime = date("Y-m-d 00:00:00", strtotime($v) - 10 * 24 * 3600);//10:天   24 小时   60  分  60秒
                $timeSql = 'SELECT publish_time FROM stable_weather_index_realtime_day_new WHERE publish_time BETWEEN ? AND ?';
                $publish_time = max(Db::query($timeSql,array($beforeTime,$v)))['publish_time'];
                $beforeSql = "SELECT stable_weather_index_value,aqi_day,predict_time as pt_time FROM stable_weather_index_realtime_day_new WHERE publish_time = '".$publish_time."' AND predict_time = '" . $v . "' AND station_id = " . $station_id;
                $beforeList = Db::query($beforeSql);
                $list = array_merge_recursive($list, $beforeList);
                $afterWeek[$k] = date('Y/m/d 20',strtotime($publish_time));
            } else {
                $afterWeek[$k] = date('Y/m/d 20',strtotime($v));
            }
        }
        $result[0] = $list;
        $result[1] = $afterWeek;
        return $result;
    }
    /**
     *   获取静稳指数预报值
     * zhugeng 2019-08-16
     * @param $station_id
     * @param $start_date
     * @param $end_date
     * @param $weekList
     * @return array|mixed
     */
    public function getForecastStable($station_id, $start_date, $end_date,$weekList)
    {
        $beforeTime = date("Y-m-d 00:00:00", strtotime($start_date) - 10 * 24 * 3600);//10:天   24 小时   60  分  60秒
        //发布日期
        $dateSql = 'SELECT publish_time FROM stable_weather_index_forecast_day WHERE publish_time BETWEEN ? AND ?';
        $publishDate = max(Db::query($dateSql,array($beforeTime,$start_date)))['publish_time'];

        $beforeSql = "SELECT stable_weather_index_value,aqi_day,predict_time as pt_time,publish_time FROM stable_weather_index_forecast_day WHERE predict_time BETWEEN '" .$start_date. "' AND '" . $end_date . "' AND publish_time = ( SELECT MAX( publish_time ) FROM stable_weather_index_forecast_day WHERE publish_time BETWEEN '" . $beforeTime . "' AND '" .
            $start_date . "') AND station_id = " . $station_id;
        $list = Db::query($beforeSql);
        $result[0] = $list;
        foreach ($weekList as $k => $v) {
            $result[1][$k] = date('Y/m/d 08',strtotime($publishDate));
        }
        return $result;
    }
    /**
     * 获取指定日期段内每一天的日期(Y-m-d)
     * @param  Date $startdate 开始日期
     * @param  Date $enddate 结束日期
     * @return Array
     */
    function getDateFromRangeYear($startdate, $enddate)
    {
        $stimestamp = strtotime($startdate);
        $etimestamp = strtotime($enddate);
        // 计算日期段内有多少天
        $days = ($etimestamp - $stimestamp) / 86400 + 1;
        // 保存每天日期
        $date = array();
        for ($i = 0; $i < $days; $i++) {
            $date[] = date('Y-m-d', $stimestamp + (86400 * $i));
        }
        return $date;
    }
}